package com.luoqiz.demo.nioDemo;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

import org.junit.Test;

public class NIOTest {

	@Test
	public void allocateTest() {
		System.out.println("*****************************************************************");
		System.out.println("测试ByteBuffer");
		System.out.println("ByteBuffer未写入数据之前");
		ByteBuffer byteBuffer = ByteBuffer.allocate(10);
		System.out.println("mark:" + byteBuffer.mark());
		System.out.println("position:" + byteBuffer.position());
		System.out.println("limit:" + byteBuffer.limit());
		System.out.println("capacity:" + byteBuffer.capacity());
		System.out.println("remaining:" + byteBuffer.remaining());
		byteBuffer.put((byte) 1);
		byteBuffer.put((byte) 2);
		byteBuffer.put((byte) 3);
		byteBuffer.put((byte) 4);
		System.out.println("---------------------------------");
		System.out.println("写入数据");
		System.out.println("ByteBuffer写入数据以后");
		System.out.println("position:" + byteBuffer.position());
		System.out.println("limit:" + byteBuffer.limit());
		System.out.println("capacity:" + byteBuffer.capacity());
		System.out.println("remaining:" + byteBuffer.remaining());
		System.out.println("数据进行flip");
		byteBuffer.flip();
		System.out.println("获取值，索引必须小于写入的数据长度");
	}

	@Test
	public void channelCopyTest() {
		System.out.println("*****************************************************************");
		System.out.println("使用FileChannel复制文件");
		try {
			RandomAccessFile srcRaf = new RandomAccessFile("d:/dome/img.jpg", "r");
			FileChannel srcFileChannel = srcRaf.getChannel();

			RandomAccessFile destRaf = new RandomAccessFile("d:/dome/img1.jpg", "rw");
			FileChannel destFielChannel = destRaf.getChannel();

			ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
			while (srcFileChannel.read(byteBuffer) != -1) {
				byteBuffer.flip();
				destFielChannel.write(byteBuffer);
				byteBuffer.clear();
			}
			destFielChannel.close();
			destRaf.close();
			srcFileChannel.close();
			srcRaf.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Test
	public void directTest() {
		System.out.println("*****************************************************************");
		System.out.println("离堆内存回收");
		ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1024 * 1024);
		try {
			Class<?> clazz=Class.forName("java.nio.DirectByteBuffer");
			Method m = clazz.getMethod("cleaner");
			m.setAccessible(true);
			Object cleaner = m.invoke(byteBuffer);
			clazz=Class.forName("sun.misc.Cleaner");
			m=clazz.getDeclaredMethod("clean");
			m.setAccessible(true);
			m.invoke(cleaner);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	}
}
